home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-07-26 | 20.5 KB | 576 lines | [TEXT/gamI] |
- (##declare
- (multilisp)
- (extended-bindings)
- (not safe)
- (not autotouch)
- (block)
- (fixnum)
- (not intr-checks))
-
- ;------------------------------------------------------------------------------
-
- ; Utilities
-
- (define (mac#unsigned16->signed16 x) ; ##vector16-ref returns 0..65535
- (##fixnum.- (##fixnum.modulo (##fixnum.+ x 32768) 65536) 32768))
-
- ; Macintosh events
-
- (define (mac#event-what ev)
- (##vector16-ref ev 0))
- (define (mac#event-message ev)
- (##fixnum.+ (##fixnum.* (##vector16-ref ev 1) 65536) (##vector16-ref ev 2)))
- (define (mac#event-when ev)
- (##fixnum.+ (##fixnum.* (##vector16-ref ev 3) 65536) (##vector16-ref ev 4)))
- (define (mac#event-where ev)
- (mac#point (##vector16-ref ev 5) (##vector16-ref ev 6)))
- (define (mac#event-modifiers ev)
- (##vector16-ref ev 7))
-
- (define (mac#modifiers-button? modifiers)
- (##fixnum.zero? (##fixnum.logand modifiers 128)))
-
- (define (mac#modifiers-command? modifiers)
- (##not (##fixnum.zero? (##fixnum.logand modifiers 256))))
-
- (define (mac#modifiers-shift? modifiers)
- (##not (##fixnum.zero? (##fixnum.logand modifiers 512))))
-
- (define (mac#modifiers-alphalock? modifiers)
- (##not (##fixnum.zero? (##fixnum.logand modifiers 1024))))
-
- (define (mac#modifiers-option? modifiers)
- (##not (##fixnum.zero? (##fixnum.logand modifiers 2048))))
-
- ; Quickdraw points
-
- (define (mac#point v h)
- (let ((p (##make-vector16 2 0)))
- (##vector16-set! p 0 v)
- (##vector16-set! p 1 h)
- p))
-
- (define (mac#point-v r) (mac#unsigned16->signed16 (##vector16-ref r 0)))
- (define (mac#point-h r) (mac#unsigned16->signed16 (##vector16-ref r 1)))
- (define (mac#point-v-set! r x) (##vector16-set! r 0 x))
- (define (mac#point-h-set! r x) (##vector16-set! r 1 x))
-
- ; Quickdraw rectangles
-
- (define (mac#rect top left bottom right)
- (let ((r (##make-vector16 4 0)))
- (##vector16-set! r 0 top)
- (##vector16-set! r 1 left)
- (##vector16-set! r 2 bottom)
- (##vector16-set! r 3 right)
- r))
-
- (define (mac#rect-top r) (mac#unsigned16->signed16 (##vector16-ref r 0)))
- (define (mac#rect-left r) (mac#unsigned16->signed16 (##vector16-ref r 1)))
- (define (mac#rect-bottom r) (mac#unsigned16->signed16 (##vector16-ref r 2)))
- (define (mac#rect-right r) (mac#unsigned16->signed16 (##vector16-ref r 3)))
- (define (mac#rect-top-set! r x) (##vector16-set! r 0 x))
- (define (mac#rect-left-set! r x) (##vector16-set! r 1 x))
- (define (mac#rect-bottom-set! r x) (##vector16-set! r 2 x))
- (define (mac#rect-right-set! r x) (##vector16-set! r 3 x))
-
- ; Quickdraw procedures
-
- (define (mac#newwindow bounds title visible procid behind goaway)
- (mac_#newwindow bounds title visible procid behind goaway))
-
- (define (mac#getnewwindow windowid behind)
- (mac_#getnewwindow windowid behind))
-
- (define (mac#disposewindow w)
- (mac_#disposewindow w))
-
- (define (mac#selectwindow w)
- (mac_#selectwindow w))
-
- (define (mac#hidewindow w)
- (mac_#hidewindow w))
-
- (define (mac#showwindow w)
- (mac_#showwindow w))
-
- (define (mac#frontwindow)
- (mac_#frontwindow))
-
- (define (mac#findwindow pt w-cell)
- (mac_#findwindow pt w-cell))
-
- (define (mac#trackgoaway w pt)
- (mac_#trackgoaway w pt))
-
- (define (mac#dragwindow w pt r)
- (mac_#dragwindow w pt r))
-
- (define (mac#invalrect port r)
- (mac_#invalrect port r))
-
- (define (mac#beginupdate w)
- (mac_#beginupdate w))
-
- (define (mac#endupdate w)
- (mac_#endupdate w))
-
- (define (mac#openport port) (mac_#openport port))
- (define (mac#initport port) (mac_#initport port))
- (define (mac#closeport port) (mac_#closeport port))
- (define (mac#setport port) (mac_#setport port))
- (define (mac#getport) (mac_#getport))
- (define (mac#setorigin port h v) (mac_#setport port h v))
- (define (mac#backpat port pat) (mac_#backpat port pat))
- (define (mac#hidecursor) (mac_#hidecursor))
- (define (mac#showcursor) (mac_#showcursor))
- (define (mac#pensize port width height) (mac_#pensize port width height))
- (define (mac#penmode port mode) (mac_#penmode port mode))
- (define (mac#penpat port pat) (mac_#penpat port pat))
- (define (mac#pennormal port) (mac_#pennormal port))
- (define (mac#moveto port h v) (mac_#moveto port h v))
- (define (mac#move port dh dv) (mac_#move port dh dv))
- (define (mac#lineto port h v) (mac_#lineto port h v))
- (define (mac#line port dh dv) (mac_#line port dh dv))
- (define (mac#textfont port font) (mac_#textfont port font))
- (define (mac#textface port face) (mac_#textface port face))
- (define (mac#textmode port mode) (mac_#textmode port mode))
- (define (mac#textsize port size) (mac_#textsize port size))
- (define (mac#spaceextra port extra) (mac_#spaceextra port extra))
- (define (mac#drawchar port ch) (mac_#drawchar port ch))
- (define (mac#drawstring port s) (mac_#drawstring port s))
- (define (mac#drawtext port textbuf firstbyte bytecount)
- (mac_#drawtext port textbuf firstbyte bytecount))
- (define (mac#charwidth port ch) (mac_#charwidth port ch))
- (define (mac#stringwidth port s) (mac_#stringwidth port s))
- (define (mac#textwidth port textbuf firstbyte bytecount)
- (mac_#textwidth port textbuf firstbyte bytecount))
- (define (mac#localtoglobal port pt) (mac_#localtoglobal port pt))
- (define (mac#globaltolocal port pt) (mac_#globaltolocal port pt))
- (define (mac#framerect port r) (mac_#framerect port r))
- (define (mac#paintrect port r) (mac_#paintrect port r))
- (define (mac#eraserect port r) (mac_#eraserect port r))
- (define (mac#invertrect port r) (mac_#invertrect port r))
- (define (mac#fillrect port r pat) (mac_#fillrect port r pat))
- (define (mac#frameroundrect port r ovwd ovht)
- (mac_#frameroundrect port r ovwd ovht))
- (define (mac#paintroundrect port r ovwd ovht)
- (mac_#paintroundrect port r ovwd ovht))
- (define (mac#eraseroundrect port r ovwd ovht)
- (mac_#eraseroundrect port r ovwd ovht))
- (define (mac#invertroundrect port r ovwd ovht)
- (mac_#invertroundrect port r ovwd ovht))
- (define (mac#fillroundrect port r ovwd ovht pat)
- (mac_#fillroundrect port r ovwd ovht pat))
- (define (mac#frameoval port r) (mac_#frameoval port r))
- (define (mac#paintoval port r) (mac_#paintoval port r))
- (define (mac#eraseoval port r) (mac_#eraseoval port r))
- (define (mac#invertoval port r) (mac_#invertoval port r))
- (define (mac#filloval port r pat) (mac_#filloval port r pat))
- (define (mac#framearc port r startangle arcangle)
- (mac_#framearc port r startangle arcangle))
- (define (mac#paintarc port r startangle arcangle)
- (mac_#paintarc port r startangle arcangle))
- (define (mac#erasearc port r startangle arcangle)
- (mac_#erasearc port r startangle arcangle))
- (define (mac#invertarc port r startangle arcangle)
- (mac_#invertarc port r startangle arcangle))
- (define (mac#fillarc port r startangle arcangle pat)
- (mac_#fillarc port r startangle arcangle pat))
-
- ; Menus
-
- (define (mac#menuselection selection) #f)
-
- (define (mac#newmenu menuid str) (mac_#newmenu menuid str))
- (define (mac#getmenu resourceid) (mac_#getmenu resourceid))
- (define (mac#disposemenu themenu) (mac_#disposemenu themenu))
- (define (mac#appendmenu themenu str) (mac_#appendmenu themenu str))
- (define (mac#addresmenu themenu thetype) (mac_#addresmenu themenu thetype))
- (define (mac#insertresmenu themenu thetype afteritem)
- (mac_#insertresmenu themenu thetype afteritem))
- (define (mac#insertmenu themenu beforeid) (mac_#insertmenu themenu beforeid))
- (define (mac#drawmenubar) (mac_#drawmenubar))
- (define (mac#deletemenu menuid) (mac_#deletemenu menuid))
- (define (mac#clearmenubar) (mac_#clearmenubar))
- (define (mac#getnewmbar menubarid) (mac_#getnewmbar menubarid))
- (define (mac#getmenubar) (mac_#getmenubar))
- (define (mac#setmenubar menulist) (mac_#setmenubar menulist))
- (define (mac#menuselect p) (mac_#menuselect p))
- (define (mac#menukey ch) (mac_#menukey ch))
- (define (mac#hilitemenu menuid) (mac_#hilitemenu menuid))
- (define (mac#disableitem themenu item) (mac_#disableitem themenu item))
- (define (mac#enableitem themenu item) (mac_#enableitem themenu item))
- (define (mac#getmhandle menuid) (mac_#getmhandle menuid))
-
- ; Standard file get/put
-
- (define (mac#sfgetfile (prompt "") (ftypes "TEXT"))
- (mac_#sfgetfile (##make-string 256 #\space) prompt ftypes))
-
- (define (mac#sfputfile (prompt "") (default ""))
- (mac_#sfputfile (##make-string 256 #\space) prompt default))
-
- ; Other procedures
-
- (define (mac#getmouse pt) (mac_#getmouse pt))
- (define (mac#button) (mac_#button))
- (define (mac#tickcount) (mac_#tickcount))
- (define (mac#delay duration) (mac_#delay duration))
- (define (mac#sysbeep duration) (mac_#sysbeep duration))
- (define (mac#seteventmask themask) (mac_#seteventmask themask))
-
- (define (mac#peek8 ptr) (mac_#peek8 ptr))
- (define (mac#poke8 ptr val) (mac_#poke8 ptr val))
- (define (mac#peek16 ptr) (mac_#peek16 ptr))
- (define (mac#poke16 ptr val) (mac_#poke16 ptr val))
- (define (mac#peek32 ptr) (mac_#peek32 ptr))
- (define (mac#poke32 ptr val) (mac_#poke32 ptr val))
-
- ; Editor windows
-
- (define (mac#edit filename (line 0) (char 0))
- (mac_#edit filename line char))
-
- ; Text windows
-
- (define (open-text-window name)
- (if (##string? name)
- (##open-input-output-file
- (##string-append (##make-string 1 (##integer->char 2)) name))
- #f))
-
- ; Online help
-
- (define (mac#help name)
- (mac_#help name))
-
- (define (help (name ""))
- (cond ((##string? name) (mac#help name))
- ((##symbol? name) (mac#help (##symbol->string name)))
- (else (mac#help ""))))
-
- ;------------------------------------------------------------------------------
-
- ; Window manager
-
- (define mac#window-bindings (##cons #f '()))
-
- (define mac#window-drag-bounds (mac#rect 0 0 32000 32000))
-
- (define (mac#window-bind w wind)
- (let ((wind-struct (##cons wind (##cons #f (##make-queue)))))
- (let loop ((prev mac#window-bindings) (pres (##cdr mac#window-bindings)))
- (if (##pair? pres)
- (let ((x (##car pres)))
- (if (##fixnum.= (##car x) w)
- (##set-cdr! x wind-struct)
- (loop pres (##cdr pres))))
- (##set-cdr! prev (##cons (##cons w wind-struct) '()))))))
-
- (define (mac#window-unbind w)
- (let loop ((prev mac#window-bindings) (pres (##cdr mac#window-bindings)))
- (if (##pair? pres)
- (let ((x (##car pres)))
- (if (##fixnum.= (##car x) w)
- (##set-cdr! prev (##cdr pres))
- (loop pres (##cdr pres))))
- #f)))
-
- (define (mac#window-lookup w)
- (let loop ((prev mac#window-bindings) (pres (##cdr mac#window-bindings)))
- (if (##pair? pres)
- (let ((x (##car pres)))
- (if (##fixnum.= (##car x) w)
- (##cdr x)
- (loop pres (##cdr pres))))
- #f)))
-
- (define (mac#window-reset w)
- (let ((wind-struct (mac#window-lookup w)))
- (if wind-struct
- (##set-cdr! wind-struct (##cons #f (##make-queue))))
- #f))
-
- (define (mac#window-handle-event wind-struct event)
-
- (define (send-window-event wind event)
- (let ((what (mac#event-what event)))
- (cond ((##fixnum.= what 0)
- ((wind 'GOAWAY)))
- ((or (##fixnum.= what 1)
- (##fixnum.= what 2))
- ((wind (cond ((##fixnum.= what 1) 'MOUSEDOWN)
- (else 'MOUSEUP)))
- (mac#event-where event)
- (mac#event-modifiers event)))
- ((or (##fixnum.= what 3)
- (##fixnum.= what 4)
- (##fixnum.= what 5))
- ((wind (cond ((##fixnum.= what 3) 'KEYDOWN)
- ((##fixnum.= what 4) 'KEYUP)
- (else 'AUTOKEY)))
- (##type-cast (##fixnum.logand (mac#event-message event) 255) 7)
- (mac#event-modifiers event)))
- ((##fixnum.= what 6)
- ((wind 'UPDATE)))
- ((##fixnum.= what 8)
- (if (##fixnum.odd? (mac#event-modifiers event))
- ((wind 'ACTIVATE))
- ((wind 'DEACTIVATE)))))))
-
- (let* ((wind (##car wind-struct))
- (sequentializer (##cdr wind-struct))
- (pending-events (##cdr sequentializer)))
- (if (##car sequentializer)
-
- (##queue-put! pending-events event) ; queue event on window
-
- (begin
- (##set-car! sequentializer #t)
- (future ; spawn a task to handle the window's events
- (let loop ((event event))
- (send-window-event wind event)
- (let ((x (##queue-get! pending-events)))
- (if x
- (loop (##car x))
- (##set-car! sequentializer #f))))))))
-
- #f)
-
- (define (mac#event-handler event)
-
- ; IMPORTANT NOTE:
- ;
- ; Event handling must be done atomically to preserve the ordering
- ; of the events. Events are generated and handled in bursts every time
- ; there is a timer interrupt (roughly 10 times a second). If interrupts
- ; were enabled and the handling of an event took too long (> 1/10 sec),
- ; for example if a garbage collection occurs in the middle of processing
- ; or there is a user interrupt, then it would be possible for the handling
- ; of a later event to start and complete before the processing of the
- ; original event is finished.
- ;
- ; To solve this problem, this procedure is written so that it
- ; does not cons and does not allow interrupts (interrupt checks are
- ; not generated inside the procedure and no procedure which might check
- ; interrupts is called). To prevent consing this procedure mutates
- ; constants (this is OK in Gambit even though it is an error in IEEE-Scheme).
- ;
- ; In addition, each window has an associated queue of pending events.
- ; Only one event per window can be processed at a time. If an event is
- ; generated for a particular window and that window is still processing a
- ; previous event, the event is put on the window's queue. When the
- ; processing of an event ends, the next event on the queue is processed (if
- ; there is one). Unfortunately, this means that if the processing of an
- ; event is aborted (due to an error or user interrupt), the window will
- ; not accept any new events. The procedure call (mac#window-reset wind)
- ; can be used to reenable the processing of new events on the window 'wind'.
- ;
- ; The processing of a window's events is done in a task (created by a
- ; future). This means that multiple windows may be "running" concurrently
- ; with the main program. This introduces the usual multitasking problems.
- ; Shared data structures should be protected with semaphores to guarantee
- ; that only one task is accessing them at any given point in time.
-
- (let* ((what (##vector16-ref event 0))
- (message (##fixnum.+ (##fixnum.* (##vector16-ref event 1) 65536)
- (##vector16-ref event 2)))
- (w-cell '(0)) ; these two constants get mutated (to avoid consing)
- (where "1234"))
- (cond ((or (##fixnum.= what 1) ; mousedown event
- (##fixnum.= what 2)) ; mouseup event
- (##vector16-set! where 0 (##vector16-ref event 5)) ; mutate 'where'
- (##vector16-set! where 1 (##vector16-ref event 6))
- (let* ((in (mac#findwindow where w-cell)) ; mutate 'w-cell'
- (w (##car w-cell))
- (wind-struct (mac#window-lookup w)))
- (if wind-struct
- (cond ((##fixnum.= in 3) ; incontent
- (if (##fixnum.= w (mac#frontwindow))
- (begin
- (mac#globaltolocal w where)
- (##vector16-set! event 5 (##vector16-ref where 0))
- (##vector16-set! event 6 (##vector16-ref where 1))
- (mac#window-handle-event wind-struct event))
- (begin
- (if (##fixnum.= what 1) (mac#selectwindow w))
- #f)))
- ((##fixnum.= in 4) ; indrag
- (if (##fixnum.= what 1)
- (mac#dragwindow w where mac#window-drag-bounds))
- #f)
- ((##fixnum.= in 6) ; ingoaway
- (if (and (##fixnum.= what 1) (mac#trackgoaway w where))
- (begin
- (##vector16-set! event 0 0)
- (mac#window-handle-event wind-struct event))
- #f)))
- (##os-handle-event event))))
- ((or (##fixnum.= what 3) ; keydown event
- (##fixnum.= what 4) ; keyup event
- (##fixnum.= what 5)) ; autokey event
- (if (mac#modifiers-command? (##vector16-ref event 7)) ; command?
- (##os-handle-event event)
- (let* ((w (mac#frontwindow))
- (wind-struct (mac#window-lookup w)))
- (if wind-struct
- (mac#window-handle-event wind-struct event)
- (##os-handle-event event)))))
- ((##fixnum.= what 6) ; update event
- (let ((wind-struct (mac#window-lookup message)))
- (if wind-struct
- (begin
- (mac#beginupdate message) ; discard update region
- (mac#endupdate message)
- (mac#window-handle-event wind-struct event))
- (##os-handle-event event))))
- ((##fixnum.= what 8) ; activate and deactivate events
- (let ((wind-struct (mac#window-lookup message)))
- (if wind-struct
- (mac#window-handle-event wind-struct event)
- (##os-handle-event event))))
- (else
- (##os-handle-event event)))))
-
- (set! ##handle-os-event mac#event-handler)
-
- ;------------------------------------------------------------------------------
-
- ; Drawing window
-
- (define clear-graphics #f)
- (define position-pen #f)
- (define draw-line-to #f)
- (define draw-point #f)
- (define clear-point #f)
- (define graphics-text #f)
-
- (let ()
-
- (define top 40)
- (define right 510)
- (define y-max 200.) ; must be inexact (flonum)
- (define x-max 200.) ; " "
- (define scaling .5) ; " "
- (define visible? #f)
-
- (define (cx x)
- (##flonum.->fixnum
- (##flonum.* (##flonum.+ x-max (##real-part (##exact->inexact x)))
- scaling)))
-
- (define (cy y)
- (##flonum.->fixnum
- (##flonum.* (##flonum.- y-max (##real-part (##exact->inexact y)))
- scaling)))
-
- (let* ((clear-rect (mac#rect -32000 -32000 32000 32000))
- (width (##flonum.->fixnum (##flonum.* (##flonum.* 2. x-max) scaling)))
- (height (##flonum.->fixnum (##flonum.* (##flonum.* 2. y-max) scaling)))
- (w (mac#newwindow
- (mac#rect top (##fixnum.- right width) (##fixnum.+ top height) right)
- "Drawing" visible? 19 (if visible? -1 0) #t))
- (head (##cons #f '()))
- (tail head)
- (pen-x0 (cx 0))
- (pen-y0 (cy 0))
- (pen-x #f)
- (pen-y #f))
-
- (define (wind msg)
- (cond ((##eq? msg 'GOAWAY) goaway)
- ((##eq? msg 'UPDATE) update)
- (else ##list))) ; discard other events
-
- (define (goaway)
- (mac#hidewindow w))
-
- (define (update)
- (set! pen-x pen-x0)
- (set! pen-y pen-y0)
- (let loop ((l (##cdr head)))
- (if (##pair? l)
- (begin ((##car l)) (loop (##cdr l))))))
-
- (define (show)
- (if (##fixnum.zero? (mac#peek8 (##fixnum.+ w 110))) ; not visible?
- (begin
- (mac#showwindow w) ; make it visible
- (mac#selectwindow w)))) ; and in front of all other windows
-
- (define (clear)
- (##set-cdr! head '())
- (set! tail head)
- (mac#eraserect w clear-rect))
-
- (define (add action)
- (let ((x (##cons action '())))
- (##set-cdr! tail x)
- (set! tail x)
- (show)
- (action)))
-
- (define (init)
- (set! pen-x pen-x0)
- (set! pen-y pen-y0)
- (clear))
-
- (define (make-position-pen x y)
- (lambda ()
- (set! pen-x x)
- (set! pen-y y)))
-
- (define (make-draw-line-to x y)
- (lambda ()
- (mac#moveto w pen-x pen-y)
- (mac#lineto w x y)
- (set! pen-x x)
- (set! pen-y y)))
-
- (define (make-draw-point x y)
- (lambda ()
- (mac#moveto w x y)
- (mac#lineto w x y)))
-
- (define (make-clear-point x y)
- (lambda ()
- (mac#penmode w 11) ; patBic
- (mac#moveto w x y)
- (mac#lineto w x y)
- (mac#penmode w 8))) ; patCopy
-
- (define (make-graphics-text text x y)
- (lambda ()
- (mac#moveto w x y)
- (mac#drawstring w text)))
-
- (set! clear-graphics
- (lambda () (show) (clear) #f))
-
- (set! position-pen
- (lambda (x y) (add (make-position-pen (cx x) (cy y))) #f))
-
- (set! draw-line-to
- (lambda (x y) (add (make-draw-line-to (cx x) (cy y))) #f))
-
- (set! draw-point
- (lambda (x y) (add (make-draw-point (cx x) (cy y))) #f))
-
- (set! clear-point
- (lambda (x y) (add (make-clear-point (cx x) (cy y))) #f))
-
- (set! graphics-text
- (lambda (text x y)
- (if (##string? text) (add (make-graphics-text text (cx x) (cy y))))
- #f))
-
- (mac#textfont w 4) ; monaco
- (mac#textsize w 9)
-
- (init)
-
- (mac#window-bind w wind)))
-
- ;------------------------------------------------------------------------------
-